require "import"
import "android.widget.*"
import "android.view.*"
import "cjson"
import "os"
import "android.app.AlertDialog"
import "android.widget.PopupMenu"
import "android.content.Context"

-- URLs das APIs
local exchangeRateApiUrlBase = "https://economia.awesomeapi.com.br/last/"
local stockApiUrlBase = "https://financialmodelingprep.com/api/v3/quote/"
local hgBrasilApiUrlBase = "https://api.hgbrasil.com/finance"
local apiKeyFMP = "qw9oh3cBMTb5HHoXRraEcLCiRYZP7qL5" -- Chave API do FMP
local apiKeyHGBrasil = "e710c5f3" -- Chave API do HG Brasil

-- Função para processar a resposta da API de câmbio (Cotação Fácil)
function processarRespostaCambio(jsonData, moedaOrigem, moedaDestino, quantidade)
    local success, dados = pcall(cjson.decode, jsonData)
    if not success then
        return "Erro ao processar dados de câmbio: formato inválido."
    end
    
    local chavePar = moedaOrigem .. moedaDestino
    if not dados[chavePar] then
        return "Erro: Dados da cotação para " .. moedaOrigem .. "-" .. moedaDestino .. " não encontrados."
    end
    
    local cotacao = tonumber(dados[chavePar].bid)
    local dataAtualizacao = dados[chavePar].create_date or "Desconhecida"
    local cotacaoFormatada = string.format("%.2f", cotacao)
    local valorConvertido = cotacao * (quantidade or 1)
    local valorConvertidoFormatado = string.format("%.2f", valorConvertido)
    local maxima = dados[chavePar].high or "N/A"
    local minima = dados[chavePar].low or "N/A"
    local variacao = dados[chavePar].pctChange or "N/A"
    local precoVenda = dados[chavePar].ask or "N/A"
    
    return string.format(
        "💰 Cotação atual de %s para %s:\n\n" ..
        "%s %d = %s %s\n" ..
        "Cotação unitária: %s 1 = %s %s\n" ..
        "Máxima do dia: %s\n" ..
        "Mínima do dia: %s\n" ..
        "Variação: %s%%\n" ..
        "Preço de venda: %s\n" ..
        "Última atualização: %s\n",
        dados[chavePar].code, dados[chavePar].codein, dados[chavePar].code, quantidade or 1, 
        dados[chavePar].codein, valorConvertidoFormatado, dados[chavePar].code, cotacaoFormatada, 
        dados[chavePar].codein, maxima, minima, variacao, precoVenda, dataAtualizacao
    )
end

-- Função para processar a resposta da API de bolsa (Financial Modeling Prep)
function processarRespostaBolsa(jsonData, indice, nomeIndice)
    local success, dados = pcall(cjson.decode, jsonData)
    if not success then
        return "Erro ao processar dados da bolsa: formato inválido."
    end
    
    if not dados or #dados == 0 then
        return "Erro: Dados da cotação para " .. nomeIndice .. " não encontrados. O índice pode não ser suportado no plano gratuito."
    end
    
    local quote = dados[1]
    if not quote.price then
        return "Erro: Preço não encontrado para " .. nomeIndice .. ". Verifique o símbolo ou o plano da API."
    end
    
    local preco = tonumber(quote.price) or 0
    local variacaoPercentual = tonumber(quote.changesPercentage) or 0
    local dataAtualizacao = os.date("%Y-%m-%d %H:%M:%S", quote.timestamp or os.time())
    local precoAbertura = tonumber(quote.open) or 0
    local maxima = tonumber(quote.dayHigh) or 0
    local minima = tonumber(quote.dayLow) or 0
    local volume = quote.volume or "N/A"
    local variacaoValor = tonumber(quote.change) or 0
    
    return string.format(
        "📈 %s - Resumo do Mercado\n\n" ..
        "Preço Atual: %.2f\n" ..
        "Abertura: %.2f\n" ..
        "Máxima: %.2f\n" ..
        "Mínima: %.2f\n" ..
        "Variação: %.2f (%.2f%%)\n" ..
        "Volume: %s\n" ..
        "Última Atualização: %s\n",
        nomeIndice, preco, precoAbertura, maxima, minima, 
        variacaoValor, variacaoPercentual, volume, dataAtualizacao
    )
end

-- Função para processar a resposta do endpoint geral da HG Brasil (plano gratuito)
function processarRespostaHGBrasil(jsonData)
    local success, dados = pcall(cjson.decode, jsonData)
    if not success then
        return "Erro ao processar dados da HG Brasil: formato inválido."
    end
    
    if not dados or not dados.results then
        return "Erro: Nenhum dado disponível na resposta da API."
    end
    
    local resposta = "📈 Resumo Financeiro (Plano Gratuito HG Brasil)\n\n"
    
    -- Dados de moedas
    if dados.results.currencies then
        local currencies = dados.results.currencies
        resposta = resposta .. "💱 Cotações de Moedas:\n"
        if currencies.USD then
            resposta = resposta .. string.format("USD/BRL - Compra: %.2f | Venda: %.2f | Variação: %.2f%%\n", 
                tonumber(currencies.USD.buy) or 0, tonumber(currencies.USD.sell) or 0, tonumber(currencies.USD.variation) or 0)
        end
        if currencies.EUR then
            resposta = resposta .. string.format("EUR/BRL - Compra: %.2f | Venda: %.2f | Variação: %.2f%%\n", 
                tonumber(currencies.EUR.buy) or 0, tonumber(currencies.EUR.sell) or 0, tonumber(currencies.EUR.variation) or 0)
        end
        if currencies.GBP then
            resposta = resposta .. string.format("GBP/BRL - Compra: %.2f | Venda: %.2f | Variação: %.2f%%\n", 
                tonumber(currencies.GBP.buy) or 0, tonumber(currencies.GBP.sell) or 0, tonumber(currencies.GBP.variation) or 0)
        end
        if currencies.JPY then
            resposta = resposta .. string.format("JPY/BRL - Compra: %.4f | Venda: %.4f | Variação: %.2f%%\n", 
                tonumber(currencies.JPY.buy) or 0, tonumber(currencies.JPY.sell) or 0, tonumber(currencies.JPY.variation) or 0)
        end
    end
    
    -- Dados de taxas
    if dados.results.taxes and #dados.results.taxes > 0 then
        local taxas = dados.results.taxes[1] -- Acessa o primeiro item do array
        resposta = resposta .. "\n📊 Taxas:\n"
        if taxas.cdi then
            resposta = resposta .. string.format("CDI: %.2f%% (Data: %s)\n", tonumber(taxas.cdi) or 0, taxas.date or "N/A")
        end
        if taxas.selic then
            resposta = resposta .. string.format("Selic: %.2f%% (Data: %s)\n", tonumber(taxas.selic) or 0, taxas.date or "N/A")
        end
    end
    
    -- Dados do IBOVESPA
    resposta = resposta .. "\n📈 IBOVESPA:\n"
    if dados.results.stocks and dados.results.stocks.IBOVESPA then
        local ibov = dados.results.stocks.IBOVESPA
        local pontos = (tonumber(ibov.points) and math.floor(tonumber(ibov.points))) or 0
        local variacao = tonumber(ibov.variation) or 0
        if pontos > 0 or variacao ~= 0 then
            resposta = resposta .. string.format("Pontos: %d | Variação: %.2f%%\n", pontos, variacao)
        else
            resposta = resposta .. "Dados não disponíveis.\n"
        end
    else
        resposta = resposta .. "Dados não disponíveis.\n"
    end
    
    return resposta
end

-- Lista das 20 principais moedas (Cotação Fácil)
local moedas = {
    "EUR", "JPY", "GBP", "CAD", "AUD", "CHF", "CNY", "INR", "RUB", "MXN", 
    "ZAR", "KRW", "NZD", "SGD", "USD", "TRY", "ARS", "CLP", "COP", "THB"
}

-- Lista das 20 principais bolsas (Bolsa Fácil) com símbolos corrigidos
local indices = {
    { simbolo = "SPY", nome = "S&P 500" },
    { simbolo = "QQQ", nome = "NASDAQ 100" },
    { simbolo = "DIA", nome = "Dow Jones" },
    { simbolo = "NI225", nome = "Nikkei 225" },
    { simbolo = "EWJ", nome = "MSCI Japan" },
    { simbolo = "EWH", nome = "Hang Seng" },
    { simbolo = "510050.SS", nome = "SSE 50" },
    { simbolo = "000001.SS", nome = "SSE Composite" },
    { simbolo = "EWU", nome = "FTSE 100" },
    { simbolo = "DAX", nome = "DAX" },
    { simbolo = "EWG", nome = "MSCI Germany" },
    { simbolo = "EWQ", nome = "CAC 40" },
    { simbolo = "^BVSP", nome = "IBOVESPA" },
    { simbolo = "EWY", nome = "KOSPI" },
    { simbolo = "EWA", nome = "ASX 200" },
    { simbolo = "INDA", nome = "BSE Sensex" },
    { simbolo = "INDY", nome = "NIFTY 50" },
    { simbolo = "EWL", nome = "SMI" },
    { simbolo = "EWC", nome = "S&P/TSX" },
    { simbolo = "EWN", nome = "AEX" }
}

-- Variáveis globais
local moedaSelecionadaAtual = "EUR"
local indiceSelecionadoAtual = indices[1]

-- Primeiro Layout (Cotação Fácil)
local layout1Def = {
    LinearLayout,
    orientation = "vertical",
    layout_width = "match_parent",
    layout_height = "match_parent",
    backgroundColor = "#000000",
    padding = "10dp",
    id = "layout1",
    {
        ScrollView,
        layout_width = "match_parent",
        layout_height = "0dp",
        layout_weight = "1",
        {
            LinearLayout,
            orientation = "vertical",
            layout_width = "match_parent",
            layout_height = "wrap_content",
            {
                TextView,
                id = "textoResposta1",
                layout_width = "match_parent",
                layout_height = "wrap_content",
                text = "Seja bem-vindo ao Cotação Fácil. Clique em 'USD-BRL' ou selecione uma moeda e clique em 'Consultar Cotação'.",
                textSize = "16sp",
                textColor = "#ffffff",
                padding = "10dp",
            },
        },
    },
    {
        Button,
        text = "USD-BRL",
        id = "botaoPesquisarCambio",
        textColor = "#ffffff",
        backgroundColor = "#00AA00",
        layout_width = "wrap_content",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            botaoPesquisarCambio.setEnabled(false)
            botaoOutraMoeda.setEnabled(false)
            textoResposta1.setText("Verificando a cotação, por favor aguarde...")
            service.speak("Verificando a cotação, por favor aguarde...")
            
            local url = exchangeRateApiUrlBase .. "USD-BRL"
            Http.get(url, function(status, dados)
                botaoPesquisarCambio.setEnabled(true)
                botaoOutraMoeda.setEnabled(true)
                
                if status == 200 and dados then
                    local quantidade = tonumber(editQuantidade.getText().toString()) or 1
                    local dadosProcessados = processarRespostaCambio(dados, "USD", "BRL", quantidade)
                    textoResposta1.setText(dadosProcessados)
                    botaoMoedaSelecionada.setText("Escolha a Moeda 1 de 20 USD")
                    moedaSelecionadaAtual = "USD"
                    local cotacao = dadosProcessados:match("USD %d+ = [%d.]+ BRL")
                    if cotacao then
                        service.speak("Cotação do dólar: " .. cotacao)
                    else
                        service.speak("Erro ao obter a cotação.")
                    end
                else
                    textoResposta1.setText("Erro ao conectar à API.")
                    service.speak("Erro ao conectar à API.")
                end
            end)
        end,
    },
    {
        Button,
        id = "botaoMoedaSelecionada",
        text = "Escolha a Moeda 1 de 20 EUR",
        textColor = "#ffffff",
        backgroundColor = "#555555",
        layout_width = "match_parent",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            local context = view.getContext()
            local menu = PopupMenu(context, view)
            for i, moeda in ipairs(moedas) do
                menu.getMenu().add(moeda)
            end
            menu.setOnMenuItemClickListener({
                onMenuItemClick = function(item)
                    moedaSelecionadaAtual = item.getTitle()
                    botaoMoedaSelecionada.setText("Escolha a Moeda 1 de 20 " .. moedaSelecionadaAtual)
                    return true
                end
            })
            menu.show()
        end,
    },
    {
        EditText,
        id = "editQuantidade",
        hint = "Digite a quantidade",
        textColor = "#ffffff",
        hintTextColor = "#888888",
        layout_width = "match_parent",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        inputType = "numberDecimal",
    },
    {
        Button,
        text = "Consultar Cotação",
        id = "botaoOutraMoeda",
        textColor = "#ffffff",
        backgroundColor = "#0066AA",
        layout_width = "wrap_content",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            local moedaSelecionada = moedaSelecionadaAtual
            botaoPesquisarCambio.setEnabled(false)
            botaoOutraMoeda.setEnabled(false)
            textoResposta1.setText("Verificando a cotação para " .. moedaSelecionada .. ", por favor aguarde...")
            service.speak("Verificando a cotação para " .. moedaSelecionada .. ", por favor aguarde...")
            
            local context = view.getContext()
            local imm = context.getSystemService(Context.INPUT_METHOD_SERVICE)
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0)
            
            local url = exchangeRateApiUrlBase .. moedaSelecionada .. "-BRL"
            Http.get(url, function(status, dados)
                botaoPesquisarCambio.setEnabled(true)
                botaoOutraMoeda.setEnabled(true)
                
                if status == 200 and dados then
                    local quantidade = tonumber(editQuantidade.getText().toString()) or 1
                    local dadosProcessados = processarRespostaCambio(dados, moedaSelecionada, "BRL", quantidade)
                    textoResposta1.setText(dadosProcessados)
                    botaoMoedaSelecionada.setText("Escolha a Moeda 1 de 20 " .. moedaSelecionada)
                    local cotacao = dadosProcessados:match(moedaSelecionada .. " %d+ = [%d.]+ BRL")
                    if cotacao then
                        service.speak("Cotação de " .. moedaSelecionada .. " para Real: " .. cotacao)
                    else
                        service.speak("Erro ao obter a cotação.")
                    end
                else
                    textoResposta1.setText("Erro ao conectar à API.")
                    service.speak("Erro ao conectar à API.")
                end
            end)
        end,
    },
    {
        LinearLayout,
        orientation = "horizontal",
        layout_width = "match_parent",
        layout_height = "wrap_content",
        gravity = "center",
        {
            Button,
            text = "Fechar",
            backgroundColor = "#AA0000",
            textColor = "#ffffff",
            layout_width = "wrap_content",
            layout_height = "wrap_content",
            layout_margin = "5dp",
            onClick = function()
                dlg.dismiss()
            end,
        },
        {
            Button,
            text = "Ir para Bolsa Fácil",
            textColor = "#ffffff",
            backgroundColor = "#880088",
            layout_width = "wrap_content",
            layout_height = "wrap_content",
            layout_margin = "5dp",
            onClick = function()
                layout1.setVisibility(View.GONE)
                layout2.setVisibility(View.VISIBLE)
            end,
        },
    },
}

-- Segundo Layout (Bolsa Fácil)
local layout2Def = {
    LinearLayout,
    orientation = "vertical",
    layout_width = "match_parent",
    layout_height = "match_parent",
    backgroundColor = "#000000",
    padding = "10dp",
    id = "layout2",
    visibility = "gone",
    {
        ScrollView,
        layout_width = "match_parent",
        layout_height = "0dp",
        layout_weight = "1",
        {
            LinearLayout,
            orientation = "vertical",
            layout_width = "match_parent",
            layout_height = "wrap_content",
            {
                TextView,
                id = "textoResposta2",
                layout_width = "match_parent",
                layout_height = "wrap_content",
                text = "Bem-vindo ao Bolsa Fácil. Clique em 'Consultar S&P 500' ou 'Consultar Dados Financeiros' para ver informações disponíveis.",
                textSize = "16sp",
                textColor = "#ffffff",
                padding = "10dp",
            },
        },
    },
    {
        Button,
        text = "Consultar S&P 500",
        id = "botaoPesquisarBolsa",
        textColor = "#ffffff",
        backgroundColor = "#00AA00",
        layout_width = "wrap_content",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            botaoPesquisarBolsa.setEnabled(false)
            botaoOutraIndice.setEnabled(false)
            textoResposta2.setText("Consultando o mercado, por favor aguarde...")
            service.speak("Consultando o mercado, por favor aguarde...")
            
            local url = stockApiUrlBase .. "SPY?apikey=" .. apiKeyFMP
            Http.get(url, function(status, dados)
                botaoPesquisarBolsa.setEnabled(true)
                botaoOutraIndice.setEnabled(true)
                
                if status == 200 and dados then
                    local dadosProcessados = processarRespostaBolsa(dados, "SPY", "S&P 500")
                    textoResposta2.setText(dadosProcessados)
                    botaoIndiceSelecionado.setText("Índice Selecionado: S&P 500")
                    indiceSelecionadoAtual = indices[1]
                    local cotacao = dadosProcessados:match("Preço Atual: [%d.]+")
                    local variacao = dadosProcessados:match("Variação: [%-]?[%d.]+ %([%-]?[%d.]+%%%)")
                    if cotacao and variacao then
                        service.speak("Resumo do S&P 500: " .. cotacao .. ", " .. variacao)
                    else
                        service.speak("Erro ao obter os dados.")
                    end
                elseif status == 403 then
                    textoResposta2.setText("Erro 403: Acesso negado. Limite de requisições diárias pode ter sido excedido ou símbolo não suportado.")
                    service.speak("Erro 403: Acesso negado. Verifique o limite de requisições ou o símbolo.")
                else
                    textoResposta2.setText("Erro ao conectar à API. Status: " .. tostring(status))
                    service.speak("Erro ao conectar à API.")
                end
            end)
        end,
    },
    {
        Button,
        text = "Consultar Dados Financeiros",
        id = "botaoPesquisarIbovespa",
        textColor = "#ffffff",
        backgroundColor = "#FFAA00",
        layout_width = "wrap_content",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            botaoPesquisarIbovespa.setEnabled(false)
            botaoPesquisarBolsa.setEnabled(false)
            botaoOutraIndice.setEnabled(false)
            textoResposta2.setText("Consultando dados financeiros, por favor aguarde...")
            service.speak("Consultando dados financeiros, por favor aguarde...")
            
            local url = hgBrasilApiUrlBase .. "?key=" .. apiKeyHGBrasil
            Http.get(url, function(status, dados)
                botaoPesquisarIbovespa.setEnabled(true)
                botaoPesquisarBolsa.setEnabled(true)
                botaoOutraIndice.setEnabled(true)
                
                if status == 200 and dados then
                    local dadosProcessados = processarRespostaHGBrasil(dados)
                    textoResposta2.setText(dadosProcessados)
                    service.speak("Dados financeiros consultados com sucesso.")
                else
                    textoResposta2.setText("Erro ao conectar à API HG Brasil. Status: " .. tostring(status))
                    service.speak("Erro ao conectar à API HG Brasil.")
                end
            end)
        end,
    },
    {
        Button,
        id = "botaoIndiceSelecionado",
        text = "Índice Selecionado: S&P 500",
        textColor = "#ffffff",
        backgroundColor = "#555555",
        layout_width = "match_parent",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            local context = view.getContext()
            local menu = PopupMenu(context, view)
            for i, indice in ipairs(indices) do
                menu.getMenu().add(indice.nome)
            end
            menu.setOnMenuItemClickListener({
                onMenuItemClick = function(item)
                    local nomeIndice = item.getTitle()
                    indiceSelecionadoAtual = indices[table.find(indices, function(v) return v.nome == nomeIndice end)]
                    botaoIndiceSelecionado.setText("Índice Selecionado: " .. nomeIndice)
                    return true
                end
            })
            menu.show()
        end,
    },
    {
        Button,
        text = "Consultar Índice",
        id = "botaoOutraIndice",
        textColor = "#ffffff",
        backgroundColor = "#0066AA",
        layout_width = "wrap_content",
        layout_height = "wrap_content",
        layout_marginBottom = "10dp",
        onClick = function(view)
            local indiceSelecionado = indiceSelecionadoAtual
            botaoPesquisarBolsa.setEnabled(false)
            botaoOutraIndice.setEnabled(false)
            textoResposta2.setText("Consultando " .. indiceSelecionado.nome .. ", por favor aguarde...")
            service.speak("Consultando " .. indiceSelecionado.nome .. ", por favor aguarde...")
            
            local context = view.getContext()
            local imm = context.getSystemService(Context.INPUT_METHOD_SERVICE)
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0)
            
            local url = stockApiUrlBase .. indiceSelecionado.simbolo .. "?apikey=" .. apiKeyFMP
            Http.get(url, function(status, dados)
                botaoPesquisarBolsa.setEnabled(true)
                botaoOutraIndice.setEnabled(true)
                
                if status == 200 and dados then
                    local dadosProcessados = processarRespostaBolsa(dados, indiceSelecionado.simbolo, indiceSelecionado.nome)
                    textoResposta2.setText(dadosProcessados)
                    local cotacao = dadosProcessados:match("Preço Atual: [%d.]+")
                    local variacao = dadosProcessados:match("Variação: [%-]?[%d.]+ %([%-]?[%d.]+%%%)")
                    if cotacao and variacao then
                        service.speak("Resumo de " .. indiceSelecionado.nome .. ": " .. cotacao .. ", " .. variacao)
                    else
                        service.speak("Erro ao obter os dados.")
                    end
                elseif status == 403 then
                    textoResposta2.setText("Erro 403: Acesso negado. Limite de requisições diárias pode ter sido excedido ou símbolo não suportado.")
                    service.speak("Erro 403: Acesso negado. Verifique o limite de requisições ou o símbolo.")
                else
                    textoResposta2.setText("Erro ao conectar à API. Status: " .. tostring(status))
                    service.speak("Erro ao conectar à API.")
                end
            end)
        end,
    },
    {
        LinearLayout,
        orientation = "horizontal",
        layout_width = "match_parent",
        layout_height = "wrap_content",
        gravity = "center",
        {
            Button,
            text = "Voltar para Cotação Fácil",
            textColor = "#ffffff",
            backgroundColor = "#880088",
            layout_width = "wrap_content",
            layout_height = "wrap_content",
            layout_margin = "5dp",
            onClick = function()
                layout2.setVisibility(View.GONE)
                layout1.setVisibility(View.VISIBLE)
            end,
        },
        {
            Button,
            text = "Fechar",
            backgroundColor = "#AA0000",
            textColor = "#ffffff",
            layout_width = "wrap_content",
            layout_height = "wrap_content",
            layout_margin = "5dp",
            onClick = function()
                dlg.dismiss()
            end,
        },
    },
}

-- Função auxiliar para encontrar índice na tabela
function table.find(t, fn)
    for i, v in ipairs(t) do
        if fn(v) then return i end
    end
    return nil
end

-- Layout principal
mainLayout = {
    LinearLayout,
    orientation = "vertical",
    layout_width = "match_parent",
    layout_height = "match_parent",
    layout1Def,
    layout2Def,
}

-- Inicialização do diálogo principal
dlg = LuaDialog()
dlg.setTitle("Cotação e Bolsa Fácil - Desenvolvido por Marcos Souza")
local view = loadlayout(mainLayout)
dlg.setView(view)
dlg.show()

service.speak("Seja bem-vindo ao Cotação e Bolsa Fácil. Você está na página Cotação Fácil. Clique em 'USD-BRL' ou selecione uma moeda e clique em 'Consultar Cotação'.")